クエリビルダ
=============

Yii のクエリビルダはオブジェクト指向で SQL 文を書く方法を提供します。
開発者は SQL 文の個々の部分をクラスのメソッドやプロパティを使って書くことが出来ます。
そうすると、クエリビルダが異なる部分を一つの正しい SQL 文に組み上げます。
そして、さらに、組み上がった SQL 文は [データアクセスオブジェクト](/doc/guide/database.dao) で説明されている DAO メソッドを呼んで実行することが出来ます。
下記はクエリビルダの典型的な使用方法を示すもので、SELECT SQL 文をビルドするものです。

~~~
[php]
$user = Yii::app()->db->createCommand()
	->select('id, username, profile')
	->from('tbl_user u')
	->join('tbl_profile p', 'u.id=p.user_id')
	->where('id=:id', array(':id'=>$id))
	->queryRow();
~~~

クエリビルダを使うのに最も適しているのは、SQL 文を手続き的に組み上げる必要があるとき、または、SQL 文をアプリケーションの何らかの条件ロジックに基づいて組み上げる必要があるときです。
クエリビルダを使用する主な便益は以下のものです。

* 複雑な SQL 文をプログラム的に組み上げることが出来る。

* 自動的にテーブル名とカラム名を引用符号で囲んで、SQL の予約語や特殊文字との衝突を防いでくれる。

* パラメータ値も引用符号で囲み、可能なときにはパラメータバインディングを使用するので、SQL インジェクション攻撃の危険を軽減するのに役立つ。

* DB について、ある程度の抽象化を提供してくれるので、異なる DB プラットフォームへの移行を単純化できる。


クエリビルダの使用は強制されていません。
実際のところ、クエリが単純な場合は、直接に SQL 文を書く方が簡単で高速です。

> Note|注意: クエリビルダは、SQL 文として定義された既存のクエリを修正するためには使うことが出来ません。
> 例えば、下記のコードは動作しません。
>
> ~~~
> [php]
> $command = Yii::app()->db->createCommand('SELECT * FROM tbl_user');
> // 次の行は上記の SQL に WHERE 句を追加しない
> $command->where('id=:id', array(':id'=>$id));
> ~~~
>
> 換言すると、素の SQL とクエリビルダを混用してはいけない、ということです。


クエリビルダを準備する
-----------------------

Yii のクエリビルダは [CDbCommand]、すなわち、[データアクセスオブジェクト](/doc/guide/database.dao) で説明されているメインの DB クエリクラスとして提供されています。

クエリビルダの使用を開始するためには、下記のように、[CDbCommand] の新しいインスタンスを作成します。

~~~
[php]
$command = Yii::app()->db->createCommand();
~~~

すなわち、`Yii::app()->db` を使って DB 接続を取得し、次に [CDbConnection::createCommand()] を呼んで必要なコマンドのインスタンスを作成します。

[データアクセスオブジェクト](/doc/guide/database.dao) では `createCommand()` の呼出しに SQL 文全体を渡しますが、ここではそうせず、空のままにしておくことに注意して下さい。
これは、下記で説明するクエリビルダのメソッドを使って、SQL 文の個々の部分を組み上げていくことになるからです。


データを読み出すクエリを組み上げる
-------------------------------

データを読み出すクエリとは SELECT SQL 文のことです。
クエリビルダは SELECT 文の個々の部分を組み上げるための一連のメソッドを提供します。
これらのメソッドは全て [CDbCommand] のインスタンスを返しますので、この章の最初の例で示されているように、メソッドチェーンを使って呼び出すことが出来ます。

* [select()|CDbCommand::select()]: クエリの SELECT の部分を指定する
* [selectDistinct()|CDbCommand::selectDistinct]: クエリの SELECT の部分を指定すると共に DISTINCT フラグを立てる
* [from()|CDbCommand::from()]: クエリの FROM の部分を指定する
* [where()|CDbCommand::where()]: クエリの WHERE の部分を指定する
* [andWhere()|CDbCommand::andWhere() ]: クエリの WHERE の部分に `AND` 演算子で条件を追加する
* [orWhere()|CDbCommand::orWhere() ]: クエリの WHERE の部分に `OR` 演算子で条件を追加する
* [join()|CDbCommand::join()]: 内部結合のクエリ断片を追加する
* [leftJoin()|CDbCommand::leftJoin]: 左外部結合のクエリ断片を追加する
* [rightJoin()|CDbCommand::rightJoin]: 右外部結合のクエリ断片を追加する
* [crossJoin()|CDbCommand::crossJoin]: 交差結合のクエリ断片を追加する
* [naturalJoin()|CDbCommand::naturalJoin]: 自然結合のクエリ断片を追加する
* [group()|CDbCommand::group()]: クエリの GROUP BY の部分を指定する
* [having()|CDbCommand::having()]: クエリの HAVING の部分を指定する
* [order()|CDbCommand::order()]: クエリの ORDER BY の部分を指定する
* [limit()|CDbCommand::limit()]: クエリの LIMIT の部分を指定する
* [offset()|CDbCommand::offset()]: クエリの OFFSET の部分を指定する
* [union()|CDbCommand::union()]: UNION のクエリ断片を追加する


以下に、これらのクエリビルダのメソッドの使用方法を説明します。
説明を単純にするために、基礎になっているデータベースは MySQL であると仮定します。
他の DBMS を使っている場合は、テーブル名・カラム名・値を囲む引用符号が、例で示されているものとは違うものになることがあります。


### select()

~~~
[php]
function select($columns='*')
~~~

[select()|CDbCommand::select()] メソッドは、クエリの `SELECT` の部分を指定します。
`$columns` パラメータが選択されるカラムを指定します。
これは、カンマで区切ったカラム名の文字列でも、カラム名の配列でも構いません。
カラム名はテーブルプレフィックス、および/あるいは、カラム名のエイリアスを含むことが出来ます。
カラムが括弧を含んでいる (すなわち、カラムが DB の式として与えられている) 場合を除いて、カラム名は自動的に引用符号で囲まれます。

以下にいくつかの例を示します。

~~~
[php]
// SELECT *
select()
// SELECT `id`, `username`
select('id, username')
// SELECT `tbl_user`.`id`, `username` AS `name`
select('tbl_user.id, username as name')
// SELECT `id`, `username`
select(array('id', 'username'))
// SELECT `id`, count(*) as num
select(array('id', 'count(*) as num'))
~~~


### selectDistinct()

~~~
[php]
function selectDistinct($columns)
~~~

[selectDistinct()|CDbCommand::selectDistinct] メソッドは、`DISTINCT` フラグを立てることを除いて、[select()|CDbCommand::select()] メソッドと同一です。
例えば、`selectDistinct('id, username')` は次の SQL 文を生成します。

~~~
SELECT DISTINCT `id`, `username`
~~~


### from()

~~~
[php]
function from($tables)
~~~

[from()|CDbCommand::from()] メソッドは、クエリの `FROM` の部分を指定します。
`$tables` パラメータが、どのテーブルからデータを読み出すかを指定します。
これは、カンマで区切ったテーブル名の文字列でも、テーブル名の配列でも構いません。
テーブル名はスキーマプレフィックス (例えば `public.tbl_user`)、および/あるいは、テーブル名のエイリアス (例えば `tbl_user u`) を含むことが出来ます。
テーブルが括弧を含んでいる (すなわち、テーブルがサブクエリあるいは DB の式として与えられている) 場合を除いて、テーブル名は自動的に引用符号で囲まれます。
以下にいくつかの例を示します。

~~~
[php]
// FROM `tbl_user`
from('tbl_user')
// FROM `tbl_user` `u`, `public`.`tbl_profile` `p`
from('tbl_user u, public.tbl_profile p')
// FROM `tbl_user`, `tbl_profile`
from(array('tbl_user', 'tbl_profile'))
// FROM `tbl_user`, (select * from tbl_profile) p
from(array('tbl_user', '(select * from tbl_profile) p'))
~~~


### where()

~~~
[php]
function where($conditions, $params=array())
~~~

[where()|CDbCommand::where()] メソッドはクエリの `WHERE` の部分を指定します。
`$conditions` パラメータはクエリの条件を指定し、`$params` はクエリ全体にバインドされるパラメータを指定します。
`$conditions` パラメータは、文字列 (例えば `id=1`) であるか、または、下記の形式の配列です。

~~~
[php]
array(operator, operand1, operand2, ...)
~~~

ここで `operator` としては、下記のどれかを指定する事が出来ます。

* `and`: オペランドが `AND` を使って連結されます。
例えば、`array('and', 'id=1', 'id=2')` は `id=1 AND id=2` を生成します。
オペランドが配列である場合は、ここで説明しているのと同じ規則を使って文字列に変換されます。
例えば、`array('and', 'type=1', array('or', 'id=1', 'id=2'))` は `type=1 AND (id=1 OR id=2)` を生成します。
このとき、メソッドによる自動的な引用符号の追加やエスケープは行われないことに注意して下さい。

* `or`: オペランドが `OR` を使って連結されることを除いて、`and` オペレータと同一です。

* `in`: 最初のオペランドはカラムまたは DB の式でなければなりません。
そして、第2のオペランドは、そのカラムまたは DB の式が取り得る値の候補を表す配列にします。
例えば、`array('in', 'id', array(1,2,3))` は `id IN (1,2,3)` を生成します。
メソッドが適切に、カラム名を引用符号で囲み、候補の値をエスケープしてくれます。

* `not in`: 生成される条件において `IN` が `NOT IN` で置き換えられることを除いて、`in` オペレータと同一です。

* `like`: 最初のオペランドはカラムまたは DB の式でなければなりません。
そして、第2のオペランドは、そのカラムまたは DB の式と比較される単一の文字列、または文字列の配列にします。
例えば、`array('like', 'name', '%tester%')` は `name LIKE '%tester%'` を生成します。
比較される文字列が配列で与えられた場合は、複数の `LIKE` 述語が生成されて `AND` によって連結されます。
例えば、`array('like', 'name', array('%test%', '%sample%'))` は `name LIKE '%test%' AND name LIKE '%sample%'` を生成します。
メソッドが適切に、カラム名を引用符号で囲み、比較される文字列をエスケープしてくれます。

* `not like`: 生成される条件において `LIKE` が `NOT LIKE` で置き換えられることを除いて、`like` オペレータと同一です。

* `or like`: 複数の `LIKE` 述語を `OR` によって連結することを除いて、`like` オペレータと同一です。

* `or not like`: 複数の `NOT LIKE` 述語を `OR` によって連結することを除いて、`not like` オペレータと同一です。


以下に `where` の使い方の例をいくつか示します。

~~~
[php]
// WHERE id=1 or id=2
where('id=1 or id=2')
// WHERE id=:id1 or id=:id2
where('id=:id1 or id=:id2', array(':id1'=>1, ':id2'=>2))
// WHERE id=1 OR id=2
where(array('or', 'id=1', 'id=2'))
// WHERE id=1 AND (type=2 OR type=3)
where(array('and', 'id=1', array('or', 'type=2', 'type=3')))
// WHERE `id` IN (1, 2)
where(array('in', 'id', array(1, 2))
// WHERE `id` NOT IN (1, 2)
where(array('not in', 'id', array(1,2)))
// WHERE `name` LIKE '%Qiang%'
where(array('like', 'name', '%Qiang%'))
// WHERE `name` LIKE '%Qiang' AND `name` LIKE '%Xue'
where(array('like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` LIKE '%Qiang' OR `name` LIKE '%Xue'
where(array('or like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` NOT LIKE '%Qiang%'
where(array('not like', 'name', '%Qiang%'))
// WHERE `name` NOT LIKE '%Qiang%' OR `name` NOT LIKE '%Xue%'
where(array('or not like', 'name', array('%Qiang%', '%Xue%')))
~~~

オペレータに `like` を使う場合に、パターンの中で明示的にワイルドカード文字 (`%` や `_`) を指定する必要があることに注意して下さい。
さらに、パターンがユーザ入力から来る場合は、下記のコードを使って特殊文字をエスケープし、ワイルドカード文字として扱われることを防がなければなりません。

~~~
[php]
$keyword=$_GET['q'];
// % と _ をエスケープする
$keyword=strtr($keyword, array('%'=>'\%', '_'=>'\_'));
$command->where(array('like', 'title', '%'.$keyword.'%'));
~~~


### andWhere()

~~~
[php]
function andWhere($conditions, $params=array())
~~~

[andWhere()|CDbCommand::andWhere() ] メソッドは与えられた条件をクエリの `WHERE` の部分に `AND` 演算子を使って追加します。
このメソッドの動作は、条件を置き換えるのでなく追加するという点を除いて、[where()|CDbCommand::where() ] とほとんど同一です。
このメソッドのパラメータに関する詳細な情報は、[where()|CDbCommand::where() ] のドキュメントを参照して下さい。


### orWhere()

~~~
[php]
function orWhere($conditions, $params=array())
~~~

[orWhere()|CDbCommand::orWhere() ] メソッドは与えられた条件をクエリの `WHERE` の部分に `OR` 演算子を使って追加します。
このメソッドの動作は、条件を置き換えるのでなく追加するという点を除いて、[where()|CDbCommand::where() ] とほとんど同一です。
このメソッドのパラメータに関する詳細な情報は、[where()|CDbCommand::where() ] のドキュメントを参照して下さい。


### order()

~~~
[php]
function order($columns)
~~~

[order()|CDbCommand::order()] メソッドは、クエリの `ORDER BY` の部分を指定します。
`$columns` パラメータがソートに使われるカラムを指定します。
これは、カンマで区切ったカラムと並び順 (`ASC` または `DESC`) の文字列、または、カラムと並び順の配列です。
カラム名はテーブルプレフィックスを含むことが出来ます。
カラムが括弧を含んでいる (すなわち、カラムが DB の式として与えられている) 場合を除いて、カラム名は自動的に引用符号で囲まれます。

以下にいくつかの例を示します。

~~~
[php]
// ORDER BY `name`, `id` DESC
order('name, id desc')
// ORDER BY `tbl_profile`.`name`, `id` DESC
order(array('tbl_profile.name', 'id desc'))
~~~


### limit() と offset()

~~~
[php]
function limit($limit, $offset=null)
function offset($offset)
~~~

[limit()|CDbCommand::limit()] メソッドおよび [offset()|CDbCommand::offset()] メソッドは、クエリの `LIMIT` および `OFFSET` の部分を指定します。
DBMS によっては、`LIMIT` と `OFFSET` の書式がサポートされていないことがあります。
その場合は、クエリビルダは SQL 文全体を書き換えて、limit や offset の機能をシミュレートします。

以下にいくつかの例を示します。

~~~
[php]
// LIMIT 10
limit(10)
// LIMIT 10 OFFSET 20
limit(10, 20)
// OFFSET 20
offset(20)
~~~


### join() とその変種

~~~
[php]
function join($table, $conditions, $params=array())
function leftJoin($table, $conditions, $params=array())
function rightJoin($table, $conditions, $params=array())
function crossJoin($table)
function naturalJoin($table)
~~~

[join()|CDbCommand::join()] メソッドとその変種は、`INNER JOIN`、`LEFT OUTER JOIN`、`RIGHT OUTER JOIN`、`CROSS JOIN`、または `NATURAL JOIN` を使って他のテーブルを結合する方法を指定します。
`$tables` パラメータが、どのテーブルを結合するかを指定します。
テーブル名はスキーマプレフィックス、および/あるいは、テーブル名のエイリアスを含むことが出来ます。
テーブルが括弧を含んでおり、DB の式またはサブクエリであることを示している場合を除いて、テーブル名は自動的に引用符号で囲まれます。
`$condition` パラメータは結合条件を指定します。
その文法は [where()|CDbCommand::where()] の場合と同じです。
そして、`$param` はクエリ全体にバインドされるパラメータを指定します。

他のクエリビルダのメソッドと違って、結合メソッドは、呼ばれるたびに前のものに追加されることに注意して下さい。

以下にいくつかの例を示します。

~~~
[php]
// JOIN `tbl_profile` ON user_id=id
join('tbl_profile', 'user_id=id')
// LEFT JOIN `pub`.`tbl_profile` `p` ON p.user_id=id AND type=1
leftJoin('pub.tbl_profile p', 'p.user_id=id AND type=:type', array(':type'=>1))
~~~


### group()

~~~
[php]
function group($columns)
~~~

[group()|CDbCommand::group()] メソッドは、クエリの `GROUP BY` の部分を指定します。
`$columns` パラメータがグループ化されるカラムを指定します。
これは、カンマで区切ったカラム名の文字列でも、カラム名の配列でも構いません。
カラム名はテーブルプレフィックスを含むことが出来ます。
カラムが括弧を含んでいる (すなわち、カラムが DB の式として与えられている) 場合を除いて、カラム名は自動的に引用符号で囲まれます。

以下にいくつかの例を示します。

~~~
[php]
// GROUP BY `name`, `id`
group('name, id')
// GROUP BY `tbl_profile`.`name`, `id`
group(array('tbl_profile.name', 'id'))
~~~


### having()

~~~
[php]
function having($conditions, $params=array())
~~~

[having()|CDbCommand::having()] メソッドは、クエリの `HAVING` の部分を指定します。
使用方法は、[where()|CDbCommand::where()] と同じです。

以下にいくつかの例を示します。

~~~
[php]
// HAVING id=1 or id=2
having('id=1 or id=2')
// HAVING id=1 OR id=2
having(array('or', 'id=1', 'id=2'))
~~~


### union()

~~~
[php]
function union($sql)
~~~

[union()|CDbCommand::union()] メソッドは、クエリの `UNION` の部分を指定します。
これは既存の SQL に `UNION` 演算子を使って `$sql` を追加するものです。
`union()` を複数回呼ぶと、複数の SQL が既存の SQL に追加されます。

以下に例を示します。

~~~
[php]
// UNION (select * from tbl_profile)
union('select * from tbl_profile')
~~~


### クエリを実行する

上記のクエリビルダのメソッドを呼んでクエリを組み上げた後、[データアクセスオブジェクト](/doc/guide/database.dao) で説明されている DAO メソッドを呼んでクエリを実行することが出来ます。
例えば、[CDbCommand::queryRow()] を呼んで結果を一行取得したり、[CDbCommand::queryAll()] を呼んで全ての行をまとめて取得したり出来ます。
例えば、

~~~
[php]
$users = Yii::app()->db->createCommand()
	->select('*')
	->from('tbl_user')
	->queryAll();
~~~


### SQL を読み出す

クエリビルダによって組み上げられたクエリを実行する以外に、対応する SQL 文を読み出すことも出来ます。
そのためには [CDbCommand::getText()] を呼びます。

~~~
[php]
$sql = Yii::app()->db->createCommand()
	->select('*')
	->from('tbl_user')
	->text;
~~~

クエリにバインドされるべきパラメータがある場合は、[CDbCommand::params] プロパティによって読み出すことが出来ます。


### クエリをビルドする代替の文法

時として、メソッドチェインを用いてクエリをビルドするのが最善の選択ではない場合もあります。
Yii のクエリビルダでは、単純なオブジェクトプロパティへの代入を使ってクエリをビルドすることも出来ます。
具体的に言うと、全てのクエリビルダのメソッドには、それに対応する同じ名前のプロパティがあります。
プロパティに値を代入することは、それに対応するメソッドを呼ぶことと等価です。
例えば、次の二つの文は等価です (`$command` は [CDbCommand] オブジェクトを表すものとします)。

~~~
[php]
$command->select(array('id', 'username'));
$command->select = array('id', 'username');
~~~

さらに加えて、[CDbConnection::createCommand()] メソッドはパラメータとして配列を取ることが出来ます。
配列内の "名前-値" のペアは、作成される [CDbCommand] インスタンスのプロパティを初期化するのに使われます。
すなわち、クエリをビルドするのに下記のコードを使うことが出来るという事です。

~~~
[php]
$row = Yii::app()->db->createCommand(array(
	'select' => array('id', 'username'),
	'from' => 'tbl_user',
	'where' => 'id=:id',
	'params' => array(':id'=>1),
))->queryRow();
~~~


### 複数のクエリをビルドする

[CDbCommand] のインスタンスを複数回再利用して、複数のクエリをビルドすることが出来ます。
ただし、新しいクエリをビルドする前に、[CDbCommand::reset()] メソッドを呼び出して、前のクエリをクリーンアップしなければなりません。
例えば

~~~
[php]
$command = Yii::app()->db->createCommand();
$users = $command->select('*')->from('tbl_users')->queryAll();
$command->reset();  // 前のクエリをクリーンアップする
$posts = $command->select('*')->from('tbl_posts')->queryAll();
~~~


データを操作するクエリをビルドする
----------------------------------

データを操作するクエリとは、DB テーブルの中のデータを挿入、更新、および、削除する SQL 文を指すものです。
これらのクエリに対応するものとして、クエリビルダはそれぞれ `insert`、`update`、`delete` というメソッドを提供しています。
上で説明した SELECT クエリのメソッドと違って、これらデータ操作クエリのメソッドは、どれも、完全な SQL 文をビルドして、それをただちに実行します。

* [insert()|CDbCommand::insert]: テーブルに行を挿入する
* [update()|CDbCommand::update]: テーブルの中のデータを更新する
* [delete()|CDbCommand::delete]: テーブルからデータを削除する


以下で、これらのデータ操作クエリのメソッドについて説明します。


### insert()

~~~
[php]
function insert($table, $columns)
~~~

[insert()|CDbCommand::insert] メソッドは、`INSERT` SQL 文をビルドして実行します。
`$table` パラメータは、どのテーブルに挿入するかを指定し、`$columns` は "名前-値" のペアの配列で、挿入されるカラムの値を指定するものです。
メソッドはテーブル名を引用符号で適切に囲み、挿入される値に対してパラメータバインディングを使用します。

下記がその例です。

~~~
[php]
// 次の SQL をビルドして実行する
// INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email)
$command->insert('tbl_user', array(
	'name'=>'Tester',
	'email'=>'tester@example.com',
));
~~~


### update()

~~~
[php]
function update($table, $columns, $conditions='', $params=array())
~~~

[update()|CDbCommand::update] メソッドは、`UPDATE` SQL 文をビルドして実行します。
`$table` パラメータは、どのテーブルを更新するかを指定します。
`$columns` は "名前-値" のペアの配列で、更新されるカラムの値を指定します。
`$conditions` と `$params` は、[where()|CDbCommand::where()] メソッドの場合と同じで、`UPDATE` 文の `WHERE` 句を指定するものです。
メソッドはテーブル名を引用符号で適切に囲み、更新される値に対してパラメータバインディングを使用します。

下記がその例です。

~~~
[php]
// 次の SQL をビルドして実行する
// UPDATE `tbl_user` SET `name`=:name WHERE id=:id
$command->update('tbl_user', array(
	'name'=>'Tester',
), 'id=:id', array(':id'=>1));
~~~


### delete()

~~~
[php]
function delete($table, $conditions='', $params=array())
~~~

[delete()|CDbCommand::delete] メソッドは、`DELETE` SQL 文をビルドして実行します。
`$table` パラメータは、どのテーブルのデータを削除するかを指定します。
`$conditions` と `$params` は、[where()|CDbCommand::where()] メソッドの場合と同じで、`DELETE` 文の `WHERE` 句を指定するものです。
メソッドはテーブル名を引用符号で適切に囲みます。

下記がその例です。

~~~
[php]
// 次の SQL をビルドして実行する
// DELETE FROM `tbl_user` WHERE id=:id
$command->delete('tbl_user', 'id=:id', array(':id'=>1));
~~~

スキーマを操作するクエリをビルドする
------------------------------------

データを読み出したり操作したりする通常のクエリの他に、クエリビルダはデータベースのスキーマを操作するための SQL クエリをビルドして実行する一連のメソッドを提供します。
具体的には、下記のクエリをサポートしています。

* [createTable()|CDbCommand::createTable]: テーブルを作成する
* [renameTable()|CDbCommand::renameTable]: テーブルの名前を変更する
* [dropTable()|CDbCommand::dropTable]: テーブルを削除する
* [truncateTable()|CDbCommand::truncateTable]: テーブルの行をすべて削除する
* [addColumn()|CDbCommand::addColumn]: テーブルのカラムを追加する
* [renameColumn()|CDbCommand::renameColumn]: テーブルのカラムの名前を変更する
* [alterColumn()|CDbCommand::alterColumn]: テーブルのカラムを変更する
* [addForeignKey()|CDbCommand::addForeignKey]: 外部キーを追加する (1.1.6 以降で利用可能)
* [dropForeignKey()|CDbCommand::dropForeignKey]: 外部キーを削除する (1.1.6 以降で利用可能)
* [dropColumn()|CDbCommand::dropColumn]: テーブルのカラムを削除する
* [createIndex()|CDbCommand::createIndex]: インデックスを作成する
* [dropIndex()|CDbCommand::dropIndex]: インデックスを削除する

> Info|情報: データベーススキーマを操作する実際の SQL 文は DBMS によって大きく異なりますが、クエリビルダはこれらのクエリをビルドするための統一されたインタフェースを提供しようと試みています。
これによって、データベースをある DBMS から別の DBMS に移行する作業が簡単になります。


### 抽象データ型

クエリビルダはテーブルのカラムの定義に使用出来る一連の抽象的なデータ型を導入しています。
特定の DBMS に固有で、DBMS ごとに全く異なる物理的データ型とは違って、抽象データ型は DBMS に依存しないものです。
抽象データ型がテーブルのカラムの定義に使用されると、クエリビルダはそれを対応する物理的データ型に変換します。

以下の抽象データ型がクエリビルダによってサポートされています。

* `pk`: 汎用的な主キーの型。MySQL では `int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY` に変換される
* `string`: 文字列。MySQL では `varchar(255)` に変換される。
* `text`: テキスト (長い文字列)。MySQL では `text` に変換される。
* `integer`: 整数。MySQL では `int(11)` に変換される。
* `float`: 実数。MySQL では `float` に変換される。
* `decimal`: デシマル。MySQL では `decimal` に変換される。
* `datetime`: 日付時刻。MySQL では `datetime` に変換される。
* `timestamp`: タイムスタンプ。MySQL では `timestamp` に変換される。
* `time`: 時刻。MySQL では `time` に変換される。
* `date`: 日付。MySQL では `date` に変換される。
* `binary`: バイナリデータ。MySQL では `blob` に変換される。
* `boolean`: 真偽値。MySQL では `tinyint(1)` に変換される。
* `money`: 金銭/貨幣。MySQL では `decimal(19,4)` に返還される。この型はバージョン 1.1.8 以降で使用可能。


### createTable()

~~~
[php]
function createTable($table, $columns, $options=null)
~~~

[createTable()|CDbCommand::createTable] メソッドは、テーブルを作成する SQL 文をビルドして実行します。
`$table` パラメータは、作成されるテーブルの名前を指定します。
`$columns` パラメータは、新しいテーブルのカラムを指定します。
これは 名前-定義 のペア (例えば `'username'=>'string'`) の配列として与えなければなりません。
`$options` パラメータは、生成される SQL の後に追加される何らかの SQL 断片を指定するものです。
クエリビルダはテーブル名とカラム名を適切に引用符号で囲みます。

カラムの定義を指定するときに、上で述べた抽象データ型を使用することが出来ます。
クエリビルダは、現在使われている DBMS に従って、抽象データ型を対応する物理的データ型に変換します。
例えば、MySQL では、`string` は `varchar(255)` に変換されます。

カラムの定義は、抽象データ型でないデータ型や仕様を含むことも出来ます。
それらは何も変更を加えずに生成される SQL に入れられます。
例えば、`point` は抽象データ型ではありませんので、カラムの定義で使われた場合は、結果として得られる SQL にそのままの形で出てきます。
`string NOT NULL` は `varchar(255) NOT NULL` に変換されます (つまり、抽象データ型である `string` だけが変換されます)。

下記はテーブルを作成する方法を示す例です。

~~~
[php]
// CREATE TABLE `tbl_user` (
//     `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
//     `username` varchar(255) NOT NULL,
//     `location` point
// ) ENGINE=InnoDB
createTable('tbl_user', array(
	'id' => 'pk',
	'username' => 'string NOT NULL',
	'location' => 'point',
), 'ENGINE=InnoDB')
~~~


### renameTable()

~~~
[php]
function renameTable($table, $newName)
~~~

[renameTable()|CDbCommand::renameTable]メソッドは、テーブルの名前を変更する SQL 文をビルドして実行します。
`$table` パラメータは、名前を変更されるテーブルの現在の名前を指定します。
`$newName` パラメータは、テーブルの新しい名前を指定します。
クエリビルダはテーブル名を適切に引用符号で囲みます。

下記はテーブルの名前を変更する方法を示す例です。

~~~
[php]
// RENAME TABLE `tbl_users` TO `tbl_user`
renameTable('tbl_users', 'tbl_user')
~~~


### dropTable()

~~~
[php]
function dropTable($table)
~~~

[dropTable()|CDbCommand::dropTable]メソッドは、テーブルを削除する SQL 文をビルドして実行します。
`$table` パラメータは、削除されるテーブルの名前を指定します。
クエリビルダはテーブル名を適切に引用符号で囲みます。

下記はテーブルを削除する方法を示す例です。

~~~
[php]
// DROP TABLE `tbl_user`
dropTable('tbl_user')
~~~

### truncateTable()

~~~
[php]
function truncateTable($table)
~~~

[truncateTable()|CDbCommand::truncateTable]メソッドは、テーブルの行をすべて削除する SQL 文をビルドして実行します。
`$table` パラメータは、行をすべて削除するテーブルの名前を指定します。
クエリビルダはテーブル名を適切に引用符号で囲みます。

下記はテーブルの行をすべて削除する方法を示す例です。


~~~
[php]
// TRUNCATE TABLE `tbl_user`
truncateTable('tbl_user')
~~~


### addColumn()

~~~
[php]
function addColumn($table, $column, $type)
~~~

[addColumn()|CDbCommand::addColumn] メソッドは、テーブルに新しいカラムを追加する SQL 文をビルドして実行します。
`$table` パラメータは、新しいカラムを追加されるテーブルの名前を指定します。
`$column` パラメータは、新しいカラムの名前を指定します。
そして `$type` パラメータは、新しいカラムの定義を指定するものです。
カラムの定義は、"createTable" の節で説明したように、抽象データ型を含むことが出来ます。
クエリビルダはテーブル名とカラム名を適切に引用符号で囲みます。

下記はテーブルにカラムを追加する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_user` ADD `email` varchar(255) NOT NULL
addColumn('tbl_user', 'email', 'string NOT NULL')
~~~


### dropColumn()

~~~
[php]
function dropColumn($table, $column)
~~~

[dropColumn()|CDbCommand::dropColumn] メソッドは、テーブルからカラムを削除する SQL 文をビルドして実行します。
`$table` パラメータは、カラムを削除されるテーブルの名前を指定します。
`$column` パラメータは、削除されるカラムの名前を指定します。
クエリビルダはテーブル名とカラム名を適切に引用符号で囲みます。

下記はテーブルからカラムを削除する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_user` DROP COLUMN `location`
dropColumn('tbl_user', 'location')
~~~


### renameColumn()

~~~
[php]
function renameColumn($table, $name, $newName)
~~~

[renameColumn()|CDbCommand::renameColumn] メソッドは、テーブルのカラム名を変更する SQL 文をビルドして実行します。
`$table` パラメータは、カラム名を変更されるテーブルの名前を指定します。
`$name` パラメータは古いカラム名、`$newName` パラメータは新しいカラム名を指定します。
クエリビルダはテーブル名とカラム名を適切に引用符号で囲みます。

下記はテーブルのカラム名を変更する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_users` CHANGE `name` `username` varchar(255) NOT NULL
renameColumn('tbl_user', 'name', 'username')
~~~


### alterColumn()

~~~
[php]
function alterColumn($table, $column, $type)
~~~

[alterColumn()|CDbCommand::alterColumn] メソッドは、テーブルのカラムを変更する SQL 文をビルドして実行します。
`$table` パラメータは、カラムを変更されるテーブルの名前を指定します。
`$column` パラメータは、変更されるカラムの名前を指定します。
そして `$type` パラメータは、カラムの新しい定義を指定するものです。
カラムの定義は、"createTable" の節で説明したように、抽象データ型を含むことが出来ます。
クエリビルダはテーブル名とカラム名を適切に引用符号で囲みます。

下記はテーブルのカラムを変更する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_user` CHANGE `username` `username` varchar(255) NOT NULL
alterColumn('tbl_user', 'username', 'string NOT NULL')
~~~


### addForeignKey()

~~~
[php]
function addForeignKey($name, $table, $columns,
	$refTable, $refColumns, $delete=null, $update=null)
~~~

[addForeignKey()|CDbCommand::addForeignKey] メソッドは、テーブルに外部キー制約を追加する SQL 文をビルドして実行します。
`$name` パラメータは、外部キーの名前を指定します。
`$table` パラメータと `$columns` パラメータは、外部キーが関係するテーブルとカラムの名前を指定します。
複数のカラムがある場合は、カンマで区切らなければなりません。
`$refTable` パラメータと `$refColumns` パラメータは、外部キーが参照するテーブルとカラムの名前を指定します。
`$delete` パラメータと `$update` パラメータは、それぞれ、SQL 文における `ON DELETE` オプションと `ON UPDATE` オプションを指定します。
そして `$type` パラメータは、カラムの新しい定義を指定するものです。
カラムの定義は、"createTable" の節で説明したように、抽象データ型を含むことが出来ます。
ほとんどの DBMS は以下のオプションをサポートしています。
すなわち、`RESTRICT`、 `CASCADE`、`NO ACTION`、`SET DEFAULT`、`SET NULL` というオプションです。
クエリビルダはテーブル名、インデックス名、カラム名を適切に引用符号で囲みます。

下記は外部キー制約を追加する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_profile` ADD CONSTRAINT `fk_profile_user_id`
// FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`)
// ON DELETE CASCADE ON UPDATE CASCADE
addForeignKey('fk_profile_user_id', 'tbl_profile', 'user_id',
	'tbl_user', 'id', 'CASCADE', 'CASCADE')
~~~


### dropForeignKey()

~~~
[php]
function dropForeignKey($name, $table)
~~~

[dropForeignKey()|CDbCommand::dropForeignKey] メソッドは、外部キー制約を削除する SQL 文をビルドして実行します。
`$name` パラメータは、削除する外部キー制約の名前を指定します。
`$table` パラメータは、その外部キー制約が課されているテーブルの名前を指定します。
クエリビルダはテーブル名と外部キー制約名を適切に引用符号で囲みます。

下記は外部キー制約を削除する方法を示す例です。

~~~
[php]
// ALTER TABLE `tbl_profile` DROP FOREIGN KEY `fk_profile_user_id`
dropForeignKey('fk_profile_user_id', 'tbl_profile')
~~~


### createIndex()

~~~
[php]
function createIndex($name, $table, $column, $unique=false)
~~~

[createIndex()|CDbCommand::createIndex] メソッドは、インデックスを作成する SQL 文をビルドして実行します。
`$name` パラメータは、作成されるインデックスの名前を指定します。
`$table` パラメータは、インデックスを追加されるテーブルの名前を指定します。
`$column` パラメータは、インデックスされるカラムの名前を指定します。
そして `$unique` パラメータは、ユニークなインデックスを作成するかどうかを指定するものです。
インデックスが複数のカラムから構成される場合は、カラム名をコンマで区切らなければなりません。
クエリビルダはテーブル名、インデックス名、カラム名を適切に引用符号で囲みます。

下記はインデックスを作成する方法を示す例です。

~~~
[php]
// CREATE INDEX `idx_username` ON `tbl_user` (`username`)
createIndex('idx_username', 'tbl_user', 'username')
~~~


### dropIndex()

~~~
[php]
function dropIndex($name, $table)
~~~

[dropIndex()|CDbCommand::dropIndex] メソッドは、インデックスを削除する SQL 文をビルドして実行します。
`$name` パラメータは、削除されるインデックスの名前を指定します。
`$table` パラメータは、削除されるインデックスを持っているテーブルの名前を指定します。
クエリビルダはテーブル名とインデックス名を適切に引用符号で囲みます。

下記はインデックスを削除する方法を示す例です。

~~~
[php]
// DROP INDEX `idx_username` ON `tbl_user`
dropIndex('idx_username', 'tbl_user')
~~~

<div class="revision">$Id$</div>
